package tt.dz.order.util;

import java.io.IOException;
import java.security.cert.CertificateException;
import java.security.cert.X509Certificate;
import java.text.DateFormat;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Date;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;

import javax.net.ssl.SSLContext;
import javax.net.ssl.TrustManager;
import javax.net.ssl.X509TrustManager;

import org.apache.http.HttpEntity;
import org.apache.http.NameValuePair;
import org.apache.http.client.config.AuthSchemes;
import org.apache.http.client.config.RequestConfig;
import org.apache.http.client.entity.UrlEncodedFormEntity;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.config.Registry;
import org.apache.http.config.RegistryBuilder;
import org.apache.http.conn.socket.ConnectionSocketFactory;
import org.apache.http.conn.socket.PlainConnectionSocketFactory;
import org.apache.http.conn.ssl.NoopHostnameVerifier;
import org.apache.http.conn.ssl.SSLConnectionSocketFactory;
import org.apache.http.entity.StringEntity;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.impl.conn.PoolingHttpClientConnectionManager;
import org.apache.http.message.BasicNameValuePair;
import org.apache.http.util.EntityUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.alibaba.fastjson.JSONObject;

/**
 * http请求访问帮助类
 * 
 * @author 谢龙飞
 *
 */
public class HttpUtils {
	private static Logger log = LoggerFactory.getLogger(HttpUtils.class);
	private static PoolingHttpClientConnectionManager connMgr;
	private static RequestConfig requestConfig;
	private static final int MAX_TIMEOUT = 20000;

	/** ssl链接配置 */
	private static SSLConnectionSocketFactory sslConnectionSocketFactory;

	static {

		// 设置连接池
		connMgr = new PoolingHttpClientConnectionManager();

		// 设置连接池大小
		connMgr.setMaxTotal(10);
		connMgr.setDefaultMaxPerRoute(connMgr.getMaxTotal());

		RequestConfig.Builder configBuilder = RequestConfig.custom();
		// 设置连接超时
		configBuilder.setConnectTimeout(MAX_TIMEOUT);
		// 设置读取超时
		configBuilder.setSocketTimeout(MAX_TIMEOUT);
		// 设置从连接池获取连接实例的超时
		configBuilder.setConnectionRequestTimeout(MAX_TIMEOUT);
		// 在提交请求之前 测试连接是否可用
		// configBuilder.setStaleConnectionCheckEnabled(true);
		requestConfig = configBuilder.build();
	}

	/**
	 * 发送 post请求访问本地应用并根据传递参数不同返回不同结果
	 * 
	 * @param url
	 * @param paramMap
	 * @return
	 */
	public static String postRequest(String url, Map<String, Object> paramMap, boolean jsonSubmit) {

		// 创建默认的httpClient实例.
		CloseableHttpClient httpClient = HttpClients.custom().setDefaultRequestConfig(requestConfig).build();

		// 创建httppost
		HttpPost httpPost = new HttpPost(url);
		CloseableHttpResponse response = null;
		try {

			if (!jsonSubmit) {
				// 创建参数队列
				List<NameValuePair> requestParams = new ArrayList<NameValuePair>();

				// 设置请求参数
				if (paramMap != null) {
					for (Iterator<String> iter = paramMap.keySet().iterator(); iter.hasNext();) {
						// 得到参数名
						String key = iter.next();
						requestParams.add(new BasicNameValuePair(key, paramMap.get(key).toString()));
					}
				}

				UrlEncodedFormEntity formEntity = new UrlEncodedFormEntity(requestParams, "utf-8");
				httpPost.setEntity(formEntity);
				httpPost.setHeader("Content-Type", "application/x-www-form-urlencoded;charset=utf-8");
			} else {
				StringEntity stringEntity = new StringEntity(JSONObject.toJSONString(paramMap), "utf-8");
				httpPost.setEntity(stringEntity);
				httpPost.setHeader("Content-Type", "application/json");
			}
			response = httpClient.execute(httpPost);
			HttpEntity entity = response.getEntity();
			return EntityUtils.toString(entity);
		} catch (IOException e) {
			log.error(e.getMessage());
		} finally {
			closeResources(httpClient, response);
		}
		return null;
	}

	/**
	 * 发送 post请求访问本地应用并根据传递参数不同返回不同结果
	 * 
	 * @param url
	 * @param paramMap
	 * @return
	 */
	public static String postRequestXml(String url, String xml) {

		// 创建默认的httpClient实例.
		CloseableHttpClient httpClient = HttpClients.custom().setDefaultRequestConfig(requestConfig).build();

		// 创建httppost
		HttpPost httpPost = new HttpPost(url);
		CloseableHttpResponse response = null;
		try {

			StringEntity stringEntity = new StringEntity(xml, "UTF-8");
			httpPost.setEntity(stringEntity);
			httpPost.setHeader("Content-Type", "application/xml;charset=UTF-8");
			response = httpClient.execute(httpPost);
			HttpEntity entity = response.getEntity();
			return EntityUtils.toString(entity, "UTF-8");
		} catch (IOException e) {
			log.error(e.getMessage());
		} finally {
			closeResources(httpClient, response);
		}
		return null;
	}

	/**
	 * 发送 get请求
	 * 
	 * @param urlValue
	 * @param paramMap
	 * @return
	 */
	public static String getRequest(String urlValue, Map<String, String> paramMap) {

		// 创建默认的httpClient实例.
		CloseableHttpClient httpClient = HttpClients.custom().setDefaultRequestConfig(requestConfig).build();
		CloseableHttpResponse response = null;
		try {

			boolean firstAppend = true;

			if (paramMap != null && paramMap.size() > 0) {
				for (String key : paramMap.keySet()) {
					Object value = paramMap.get(key);
					if (firstAppend) {
						if (urlValue.contains("?")) {
							urlValue += "&" + key + "=" + value;
						} else {
							urlValue += "?" + key + "=" + value;
						}
						firstAppend = false;
					} else {
						urlValue += "&" + key + "=" + value;
					}
				}
			}
			// 创建httpget.
			HttpGet httpGet = new HttpGet(urlValue);
			// 执行get请求.
			response = httpClient.execute(httpGet);
			HttpEntity entity = response.getEntity();
			return EntityUtils.toString(entity);
		} catch (IOException e) {
			log.error(e.getMessage());
		} finally {
			closeResources(httpClient, response);
		}
		return null;
	}

	/**
	 * 重写方法，取消SSL验证
	 */
	private static X509TrustManager manager = new X509TrustManager() {

		@Override
		public X509Certificate[] getAcceptedIssuers() {
			return null;
		}

		@Override
		public void checkServerTrusted(X509Certificate[] arg0, String arg1) throws CertificateException {

		}

		@Override
		public void checkClientTrusted(X509Certificate[] arg0, String arg1) throws CertificateException {
		}
	};

	/**
	 * 启用ssl
	 */
	private static void enableSSL() {
		try {
			SSLContext sslContext = SSLContext.getInstance("TLS");
			sslContext.init(null, new TrustManager[] { manager }, null);
			sslConnectionSocketFactory = new SSLConnectionSocketFactory(sslContext, NoopHostnameVerifier.INSTANCE);
		} catch (Exception e) {
			log.error(e.getMessage());
		}
	}

	/**
	 * 发送SSL请求
	 * 
	 * @param reqURL
	 * @param paramMap
	 * @param jsonSubmit
	 * @return
	 */
	public static String sendSSLPostRequest(String reqURL, Map<String, String> paramMap, boolean jsonSubmit) {

		enableSSL();

		RequestConfig reqConfig = RequestConfig.custom().setExpectContinueEnabled(true)
				.setTargetPreferredAuthSchemes(Arrays.asList(AuthSchemes.NTLM, AuthSchemes.DIGEST))
				.setProxyPreferredAuthSchemes(Arrays.asList(AuthSchemes.BASIC)).build();

		Registry<ConnectionSocketFactory> socketFactoryRegistry = RegistryBuilder.<ConnectionSocketFactory> create()
				.register("http", PlainConnectionSocketFactory.INSTANCE).register("https", sslConnectionSocketFactory)
				.build();

		// 设置连接池
		PoolingHttpClientConnectionManager clientConnectionManager = new PoolingHttpClientConnectionManager(
				socketFactoryRegistry);

		// 获取httpclient
		CloseableHttpClient httpClient = HttpClients.custom().setConnectionManager(clientConnectionManager)
				.setDefaultRequestConfig(reqConfig).build();
		HttpPost httpPost = new HttpPost(reqURL);
		CloseableHttpResponse response = null;
		try {
			if (!jsonSubmit) {
				// 创建参数队列
				List<NameValuePair> requestParams = new ArrayList<NameValuePair>();

				// 设置请求参数
				if (paramMap != null) {
					for (Iterator<String> iter = paramMap.keySet().iterator(); iter.hasNext();) {
						// 得到参数名
						String key = iter.next();
						String value = paramMap.get(key);
						requestParams.add(new BasicNameValuePair(key, value));
					}
				}
				// 表单编码实体
				UrlEncodedFormEntity formEntity = new UrlEncodedFormEntity(requestParams, "utf-8");
				httpPost.setEntity(formEntity);
				httpPost.setHeader("Content-Type", "application/x-www-form-urlencoded;charset=utf-8");
			} else {
				StringEntity stringEntity = new StringEntity(JSONObject.toJSONString(paramMap), "utf-8");
				httpPost.setEntity(stringEntity);
				httpPost.setHeader("Content-Type", "application/json");
			}
			// 执行请求
			response = httpClient.execute(httpPost);
			HttpEntity entity = response.getEntity();
			return EntityUtils.toString(entity);
		} catch (IOException e) {
			log.error(e.getMessage());
		} finally {
			// 关闭连接,释放资源
			closeResources(httpClient, response);
		}
		return null;
	}

	/**
	 * 关闭资源
	 * 
	 * @param httpClient
	 * @param response
	 */
	private static void closeResources(CloseableHttpClient httpClient, CloseableHttpResponse response) {
		try {
			if (response != null) {
				response.close();
			}
		} catch (IOException e) {
			log.error(e.getMessage());
		}
		try {
			httpClient.close();
		} catch (IOException e) {
			log.error(e.getMessage());
		}
	}

	public static void main(String[] args) throws ParseException {

		Map<String, String> map = new HashMap<String, String>();
		map.put("username", "你6");
		// map.put("password", "137964635qq_com1");
		// String resultStr = HttpUtil.sendSSLPostRequest(
		// "http://a1.easemob.com/leeyx/dianzhuang/users", map, true);
		// String resultStr1 = HttpUtil.getRequest("http://www.baidu.com", map);
		// System.out.println(resultStr1);
		DateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
		System.out.println(dateFormat.parse("2016-01-21 18:10:50").getTime() - new Date().getTime());
		System.out.println(new Date().getTime() / 1000);
		System.out.println(new Date().getTime());
	}
}
